﻿using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

namespace Known.EntityFramework;

/// <summary>
/// 数据上下文类。
/// </summary>
public class DataContext : DbContext
{
    internal static DbContextOption Option { get; set; }

    /// <summary>
    /// 数据上下文配置。
    /// </summary>
    /// <param name="optionsBuilder">配置建造者。</param>
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        Option.OnConfig?.Invoke(optionsBuilder);
    }

    /// <summary>
    /// 数据模型配置。
    /// </summary>
    /// <param name="modelBuilder">模型建造者。</param>
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Ignore<CodeInfo>();
        modelBuilder.Ignore<PageInfo>();
        modelBuilder.Ignore<FormInfo>();

        foreach (var item in DbConfig.Models)
        {
            modelBuilder.Entity(item.Type).HasKey(item.Keys.ToArray());
        }

        Option.OnModel?.Invoke(modelBuilder);

        var entityTypes = modelBuilder.Model.GetEntityTypes().ToList();
        for (int i = 0; i < entityTypes.Count; i++)
        {
            var entity = entityTypes[i];
            //忽略非实体类
            //if (entity.ClrType.BaseType != typeof(EntityBase))
            //    modelBuilder.Ignore(entity.ClrType);
            //设置实体主键
            //modelBuilder.Entity(entity.ClrType).HasKey(nameof(EntityBase.Id));

            foreach (var property in entity.ClrType.GetProperties())
            {
                //忽略实体虚拟属性
                if (property.GetMethod != null && property.GetMethod.IsVirtual)
                    modelBuilder.Entity(entity.ClrType).Ignore(property.Name);

                //属性值转换
                if (property.SetMethod != null && !property.GetMethod.IsVirtual && property.PropertyType == typeof(bool))
                {
                    modelBuilder.Entity(entity.ClrType)
                                .Property(property.Name)
                                .HasConversion(new BoolToStringConverter("False", "True"));
                }

                //if (property.PropertyType.IsEnum)
                //{
                //    modelBuilder.Entity(entity.ClrType)
                //                .Property(property.Name)
                //                .HasConversion(new EnumConverter());
                //}
            }
        }
    }
}

//class EnumConverter : ValueConverter
//{
//    public override Func<object, object> ConvertToProvider { get; }
//    public override Func<object, object> ConvertFromProvider { get; }
//    public override Type ModelClrType { get; }
//    public override Type ProviderClrType { get; }
//}